package com.n3wax.automation.security.ademco.ad2usb;

import javax.comm.*;
import java.io.*;
import java.util.TooManyListenersException;

public class AD2USBCommInterface implements Runnable, SerialPortEventListener{

    private AD2USBEventConsumer consumer;
    private CommPortIdentifier commPortIdent;
    private SerialPort serPort;
    private InputStream inStream;
    private OutputStream outStream;
    private BufferedReader reader;
    private Thread readThread;
    boolean dataSent = false;

    public AD2USBCommInterface(AD2USBEventConsumer evConsumer)
    {
        consumer = evConsumer;
        initializeSerial();
    }

    protected AD2USBCommInterface()
    {

    }

    private void initializeSerial() {
        try {
            commPortIdent = CommPortIdentifier.getPortIdentifier("COM10");
        } catch (NoSuchPortException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

        try {
            serPort = (SerialPort) commPortIdent.open("AD2USB",2000);
        } catch (PortInUseException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

        try {
            inStream = serPort.getInputStream();
            outStream = serPort.getOutputStream();
            reader = new BufferedReader(new InputStreamReader(inStream));

            serPort.addEventListener(this);
            serPort.notifyOnDataAvailable(true);

        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (TooManyListenersException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

        try {
            serPort.setSerialPortParams(115200,
                SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1,
                SerialPort.PARITY_NONE);
        } catch (UnsupportedCommOperationException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

        //serPort.setDTR(false);
        System.out.println("Starting thread");
        readThread = new Thread(this);
        readThread.start();
    }


    public void run() {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {}

    }

    public void serialEvent(SerialPortEvent event) {

        switch(event.getEventType()) {
                case SerialPortEvent.BI:
                case SerialPortEvent.OE:
                case SerialPortEvent.FE:
                case SerialPortEvent.PE:
                case SerialPortEvent.CD:
                case SerialPortEvent.CTS:
                case SerialPortEvent.DSR:
                case SerialPortEvent.RI:
                case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
                    break;
                case SerialPortEvent.DATA_AVAILABLE:
                    String data = null;
                    try {
                        data = reader.readLine();

                        if(data.substring(0,1).equalsIgnoreCase("["))
                        {
                            System.out.println(data);
                            callbackEvent(parseBitmap(data), parseNumericMessage(data), parsePanelMessage(data));
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    break;

    }
    }

    //format:
    //[000003011000--------],35,[f700001b1035030028020000],"FAULT 35 LIBRARYSOUTH DOOR      "

    protected String parseBitmap(String rawData)
    {
        String parsedEvent = null;
        parsedEvent = rawData.substring(1,21);
        return parsedEvent;
    }

    protected String parseNumericMessage(String rawData)
    {
        String parsedEvent = null;
        parsedEvent = rawData.substring(24,26);
        return parsedEvent;
    }

    protected String parsePanelMessage(String rawData)
    {
        String parsedEvent = null;
        parsedEvent = rawData.substring(54,86);
        return parsedEvent;
    }

    private void callbackEvent(String bitmap, String numericMessage, String panelMessage)
    {
        consumer.receiveEvent(bitmap, numericMessage, panelMessage);
    }

    public void sendCommand(String command)
    {
        try {
            for(int ctr=0; ctr<command.length();ctr++)
            {
                char cmdChar = command.charAt(ctr);
                outStream.write((int)cmdChar);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
